// Copyright Epic Games, Inc. All Rights Reserved.

#include "LyraGameplayAbility.h"
#include "LyraLogChannels.h"
#include "AbilitySystem/LyraAbilitySystemComponent.h"
#include "AbilitySystemLog.h"
#include "Player/LyraPlayerController.h"
#include "Character/LyraCharacter.h"
#include "LyraGameplayTags.h"
#include "LyraAbilityCost.h"
#include "Character/LyraHeroComponent.h"
#include "AbilitySystemBlueprintLibrary.h"
#include "AbilitySystemGlobals.h"
#include "LyraAbilitySimpleFailureMessage.h"
#include "GameFramework/GameplayMessageSubsystem.h"
#include "AbilitySystem/LyraAbilitySourceInterface.h"
#include "AbilitySystem/LyraGameplayEffectContext.h"
#include "Physics/PhysicalMaterialWithTags.h"
#include "GameFramework/PlayerState.h"
#include "Camera/LyraCameraMode.h"

#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraGameplayAbility)

// 宏定义：确保能力已实例化，否则返回
#define ENSURE_ABILITY_IS_INSTANTIATED_OR_RETURN(FunctionName, ReturnValue)																				\
{																																						\
	if (!ensure(IsInstantiated()))																														\
	{																																					\
		ABILITY_LOG(Error, TEXT("%s: " #FunctionName " cannot be called on a non-instanced ability. Check the instancing policy."), *GetPathName());	\
		return ReturnValue;																																\
	}																																					\
}

// 定义游戏标签：简单失败消息和播放蒙太奇失败消息
UE_DEFINE_GAMEPLAY_TAG(TAG_ABILITY_SIMPLE_FAILURE_MESSAGE, "Ability.UserFacingSimpleActivateFail.Message");
UE_DEFINE_GAMEPLAY_TAG(TAG_ABILITY_PLAY_MONTAGE_FAILURE_MESSAGE, "Ability.PlayMontageOnActivateFail.Message");

/**
 * 构造函数，初始化能力的基本属性
 */
ULyraGameplayAbility::ULyraGameplayAbility(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	// 设置复制策略为不复制
	ReplicationPolicy = EGameplayAbilityReplicationPolicy::ReplicateNo;
	// 设置实例化策略为每个Actor实例化
	InstancingPolicy = EGameplayAbilityInstancingPolicy::InstancedPerActor;
	// 设置网络执行策略为本地预测
	NetExecutionPolicy = EGameplayAbilityNetExecutionPolicy::LocalPredicted;
	// 设置网络安全策略为客户端或服务器
	NetSecurityPolicy = EGameplayAbilityNetSecurityPolicy::ClientOrServer;

	// 设置激活策略为输入触发
	ActivationPolicy = ELyraAbilityActivationPolicy::OnInputTriggered;
	// 设置激活组为独立
	ActivationGroup = ELyraAbilityActivationGroup::Independent;

	// 默认不记录取消
	bLogCancelation = false;

	// 初始化活动相机模式为空
	ActiveCameraMode = nullptr;
}

/**
 * 从Actor信息中获取Lyra能力系统组件
 */
ULyraAbilitySystemComponent* ULyraGameplayAbility::GetLyraAbilitySystemComponentFromActorInfo() const
{
	// 如果当前Actor信息有效，则转换为Lyra能力系统组件
	return (CurrentActorInfo ? Cast<ULyraAbilitySystemComponent>(CurrentActorInfo->AbilitySystemComponent.Get()) : nullptr);
}

/**
 * 从Actor信息中获取Lyra玩家控制器
 */
ALyraPlayerController* ULyraGameplayAbility::GetLyraPlayerControllerFromActorInfo() const
{
	// 如果当前Actor信息有效，则转换为Lyra玩家控制器
	return (CurrentActorInfo ? Cast<ALyraPlayerController>(CurrentActorInfo->PlayerController.Get()) : nullptr);
}

/**
 * 从Actor信息中获取控制器
 */
AController* ULyraGameplayAbility::GetControllerFromActorInfo() const
{
	if (CurrentActorInfo)
	{
		// 首先尝试获取玩家控制器
		if (AController* PC = CurrentActorInfo->PlayerController.Get())
		{
			return PC;
		}

		// 在所有者链中查找玩家控制器或Pawn
		AActor* TestActor = CurrentActorInfo->OwnerActor.Get();
		while (TestActor)
		{
			// 如果找到控制器，直接返回
			if (AController* C = Cast<AController>(TestActor))
			{
				return C;
			}

			// 如果找到Pawn，返回其控制器
			if (APawn* Pawn = Cast<APawn>(TestActor))
			{
				return Pawn->GetController();
			}

			// 继续向上查找所有者
			TestActor = TestActor->GetOwner();
		}
	}

	// 未找到控制器，返回空指针
	return nullptr;
}

/**
 * 从Actor信息中获取Lyra角色
 */
ALyraCharacter* ULyraGameplayAbility::GetLyraCharacterFromActorInfo() const
{
	// 如果当前Actor信息有效，则转换为Lyra角色
	return (CurrentActorInfo ? Cast<ALyraCharacter>(CurrentActorInfo->AvatarActor.Get()) : nullptr);
}

/**
 * 从Actor信息中获取英雄组件
 */
ULyraHeroComponent* ULyraGameplayAbility::GetHeroComponentFromActorInfo() const
{
	// 如果当前Actor信息有效，则查找英雄组件
	return (CurrentActorInfo ? ULyraHeroComponent::FindHeroComponent(CurrentActorInfo->AvatarActor.Get()) : nullptr);
}

/**
 * 当能力激活失败时的原生处理函数
 */
void ULyraGameplayAbility::NativeOnAbilityFailedToActivate(const FGameplayTagContainer& FailedReason) const
{
	// 标记是否找到简单失败
	bool bSimpleFailureFound = false;
	// 遍历所有失败原因标签
	for (FGameplayTag Reason : FailedReason)
	{
		// 如果尚未找到简单失败，检查是否有对应的用户界面消息
		if (!bSimpleFailureFound)
		{
			if (const FText* pUserFacingMessage = FailureTagToUserFacingMessages.Find(Reason))
			{
				// 构建简单失败消息
				FLyraAbilitySimpleFailureMessage Message;
				Message.PlayerController = GetActorInfo().PlayerController.Get();
				Message.FailureTags = FailedReason;
				Message.UserFacingReason = *pUserFacingMessage;

				// 获取游戏消息子系统并广播消息
				UGameplayMessageSubsystem& MessageSystem = UGameplayMessageSubsystem::Get(GetWorld());
				MessageSystem.BroadcastMessage(TAG_ABILITY_SIMPLE_FAILURE_MESSAGE, Message);
				bSimpleFailureFound = true;
			}
		}
		
		// 检查是否有对应的动画蒙太奇
		if (UAnimMontage* pMontage = FailureTagToAnimMontage.FindRef(Reason))
		{
			// 构建蒙太奇失败消息
			FLyraAbilityMontageFailureMessage Message;
			Message.PlayerController = GetActorInfo().PlayerController.Get();
			Message.AvatarActor = GetActorInfo().AvatarActor.Get();
			Message.FailureTags = FailedReason;
			Message.FailureMontage = pMontage;

			// 获取游戏消息子系统并广播消息
			UGameplayMessageSubsystem& MessageSystem = UGameplayMessageSubsystem::Get(GetWorld());
			MessageSystem.BroadcastMessage(TAG_ABILITY_PLAY_MONTAGE_FAILURE_MESSAGE, Message);
		}
	}
}

/**
 * 检查能力是否可以激活
 */
bool ULyraGameplayAbility::CanActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayTagContainer* SourceTags, const FGameplayTagContainer* TargetTags, FGameplayTagContainer* OptionalRelevantTags) const
{
	// 检查Actor信息和能力系统组件是否有效
	if (!ActorInfo || !ActorInfo->AbilitySystemComponent.IsValid())
	{
		return false;
	}

	// 调用父类的检查方法
	if (!Super::CanActivateAbility(Handle, ActorInfo, SourceTags, TargetTags, OptionalRelevantTags))
	{
		return false;
	}

	// 检查激活组是否被阻塞
	ULyraAbilitySystemComponent* LyraASC = CastChecked<ULyraAbilitySystemComponent>(ActorInfo->AbilitySystemComponent.Get());
	if (LyraASC->IsActivationGroupBlocked(ActivationGroup))
	{
		// 如果提供了可选相关标签容器，添加激活失败标签
		if (OptionalRelevantTags)
		{
			OptionalRelevantTags->AddTag(LyraGameplayTags::Ability_ActivateFail_ActivationGroup);
		}
		return false;
	}

	return true;
}

/**
 * 设置能力是否可以被取消
 */
void ULyraGameplayAbility::SetCanBeCanceled(bool bCanBeCanceled)
{
	// 如果能力是可替换的，则不能阻止取消
	if (!bCanBeCanceled && (ActivationGroup == ELyraAbilityActivationGroup::Exclusive_Replaceable))
	{
		UE_LOG(LogLyraAbilitySystem, Error, TEXT("SetCanBeCanceled: Ability [%s] can not block canceling because its activation group is replaceable."), *GetName());
		return;
	}

	// 调用父类的方法
	Super::SetCanBeCanceled(bCanBeCanceled);
}

/**
 * 当能力被赋予时的回调函数
 */
void ULyraGameplayAbility::OnGiveAbility(const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilitySpec& Spec)
{
	// 调用父类的方法
	Super::OnGiveAbility(ActorInfo, Spec);

	// 调用蓝图事件：能力被添加
	K2_OnAbilityAdded();

	// 尝试在生成时激活能力
	TryActivateAbilityOnSpawn(ActorInfo, Spec);
}

/**
 * 当能力被移除时的回调函数
 */
void ULyraGameplayAbility::OnRemoveAbility(const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilitySpec& Spec)
{
	// 调用蓝图事件：能力被移除
	K2_OnAbilityRemoved();

	// 调用父类的方法
	Super::OnRemoveAbility(ActorInfo, Spec);
}

/**
 * 激活能力
 */
void ULyraGameplayAbility::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData)
{
	// 调用父类的激活方法
	Super::ActivateAbility(Handle, ActorInfo, ActivationInfo, TriggerEventData);
}

/**
 * 结束能力
 */
void ULyraGameplayAbility::EndAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateEndAbility, bool bWasCancelled)
{
	// 清除相机模式
	ClearCameraMode();

	// 调用父类的结束方法
	Super::EndAbility(Handle, ActorInfo, ActivationInfo, bReplicateEndAbility, bWasCancelled);
}

/**
 * 检查能力消耗
 */
bool ULyraGameplayAbility::CheckCost(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, OUT FGameplayTagContainer* OptionalRelevantTags) const
{
	// 调用父类的检查方法，如果失败则返回false
	if (!Super::CheckCost(Handle, ActorInfo, OptionalRelevantTags) || !ActorInfo)
	{
		return false;
	}

	// 验证是否可以承担额外消耗
	for (const TObjectPtr<ULyraAbilityCost>& AdditionalCost : AdditionalCosts)
	{
		if (AdditionalCost != nullptr)
		{
			// 检查每个额外消耗
			if (!AdditionalCost->CheckCost(this, Handle, ActorInfo, /*inout*/ OptionalRelevantTags))
			{
				return false;
			}
		}
	}

	return true;
}

/**
 * 应用能力消耗
 */
void ULyraGameplayAbility::ApplyCost(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo) const
{
	// 调用父类的应用消耗方法
	Super::ApplyCost(Handle, ActorInfo, ActivationInfo);

	// 确保Actor信息有效
	check(ActorInfo);

	// Lambda函数：确定能力是否命中目标
	auto DetermineIfAbilityHitTarget = [&]()
	{
		// 检查网络权限
		if (ActorInfo->IsNetAuthority())
		{
			// 获取能力系统组件
			if (ULyraAbilitySystemComponent* ASC = Cast<ULyraAbilitySystemComponent>(ActorInfo->AbilitySystemComponent.Get()))
			{
				// 获取目标数据
				FGameplayAbilityTargetDataHandle TargetData;
				ASC->GetAbilityTargetData(Handle, ActivationInfo, TargetData);
				// 遍历目标数据，检查是否有命中结果
				for (int32 TargetDataIdx = 0; TargetDataIdx < TargetData.Data.Num(); ++TargetDataIdx)
				{
					if (UAbilitySystemBlueprintLibrary::TargetDataHasHitResult(TargetData, TargetDataIdx))
					{
						return true;
					}
				}
			}
		}

		return false;
	};

	// 支付任何额外消耗
	bool bAbilityHitTarget = false; // 能力是否命中目标
	bool bHasDeterminedIfAbilityHitTarget = false; // 是否已确定能力是否命中目标
	for (const TObjectPtr<ULyraAbilityCost>& AdditionalCost : AdditionalCosts)
	{
		if (AdditionalCost != nullptr)
		{
			// 如果消耗只在命中时应用
			if (AdditionalCost->ShouldOnlyApplyCostOnHit())
			{
				// 如果尚未确定是否命中目标，则进行确定
				if (!bHasDeterminedIfAbilityHitTarget)
				{
					bAbilityHitTarget = DetermineIfAbilityHitTarget();
					bHasDeterminedIfAbilityHitTarget = true;
				}

				// 如果能力未命中目标，跳过此消耗
				if (!bAbilityHitTarget)
				{
					continue;
				}
			}

			// 应用消耗
			AdditionalCost->ApplyCost(this, Handle, ActorInfo, ActivationInfo);
		}
	}
}

/**
 * 创建效果上下文
 */
FGameplayEffectContextHandle ULyraGameplayAbility::MakeEffectContext(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo) const
{
	// 调用父类的方法创建效果上下文
	FGameplayEffectContextHandle ContextHandle = Super::MakeEffectContext(Handle, ActorInfo);

	// 提取Lyra特定的效果上下文
	FLyraGameplayEffectContext* EffectContext = FLyraGameplayEffectContext::ExtractEffectContext(ContextHandle);
	check(EffectContext);

	// 确保Actor信息有效
	check(ActorInfo);

	// 声明变量
	AActor* EffectCauser = nullptr; // 效果引发者
	const ILyraAbilitySourceInterface* AbilitySource = nullptr; // 能力来源接口
	float SourceLevel = 0.0f; // 来源等级

	// 获取能力来源信息
	GetAbilitySource(Handle, ActorInfo, /*out*/ SourceLevel, /*out*/ AbilitySource, /*out*/ EffectCauser);

	// 获取源对象
	UObject* SourceObject = GetSourceObject(Handle, ActorInfo);

	// 获取 instigator（发起者）
	AActor* Instigator = ActorInfo ? ActorInfo->OwnerActor.Get() : nullptr;

	// 设置效果上下文的各个属性
	EffectContext->SetAbilitySource(AbilitySource, SourceLevel); // 设置能力来源和等级
	EffectContext->AddInstigator(Instigator, EffectCauser); // 添加 instigator 和效果引发者
	EffectContext->AddSourceObject(SourceObject); // 添加源对象

	return ContextHandle; // 返回上下文句柄
}

/**
 * 将能力标签应用到游戏效果规格
 */
void ULyraGameplayAbility::ApplyAbilityTagsToGameplayEffectSpec(FGameplayEffectSpec& Spec, FGameplayAbilitySpec* AbilitySpec) const
{
	// 调用父类的方法
	Super::ApplyAbilityTagsToGameplayEffectSpec(Spec, AbilitySpec);

	// 获取命中结果
	if (const FHitResult* HitResult = Spec.GetContext().GetHitResult())
	{
		// 检查物理材料是否有标签
		if (const UPhysicalMaterialWithTags* PhysMatWithTags = Cast<const UPhysicalMaterialWithTags>(HitResult->PhysMaterial.Get()))
		{
			// 将物理材料的标签添加到效果规格的目标标签中
			Spec.CapturedTargetTags.GetSpecTags().AppendTags(PhysMatWithTags->Tags);
		}
	}
}

/**
 * 检查能力是否满足标签要求
 */
bool ULyraGameplayAbility::DoesAbilitySatisfyTagRequirements(const UAbilitySystemComponent& AbilitySystemComponent, const FGameplayTagContainer* SourceTags, const FGameplayTagContainer* TargetTags, OUT FGameplayTagContainer* OptionalRelevantTags) const
{
	// 专门处理死亡排除和通过ASC扩展AbilityTags的版本

	// 声明变量
	bool bBlocked = false; // 是否被阻塞
	bool bMissing = false; // 是否缺少标签

	// 获取能力系统全局对象
	UAbilitySystemGlobals& AbilitySystemGlobals = UAbilitySystemGlobals::Get();
	// 获取阻塞标签和缺失标签
	const FGameplayTag& BlockedTag = AbilitySystemGlobals.ActivateFailTagsBlockedTag;
	const FGameplayTag& MissingTag = AbilitySystemGlobals.ActivateFailTagsMissingTag;

	// 检查此能力的任何标签当前是否被阻塞
	if (AbilitySystemComponent.AreAbilityTagsBlocked(GetAssetTags()))
	{
		bBlocked = true; // 标记为被阻塞
	}

	// 转换为Lyra能力系统组件
	const ULyraAbilitySystemComponent* LyraASC = Cast<ULyraAbilitySystemComponent>(&AbilitySystemComponent);
	// 静态变量，避免重复分配
	static FGameplayTagContainer AllRequiredTags; // 所有必需标签
	static FGameplayTagContainer AllBlockedTags; // 所有阻塞标签

	// 初始化标签容器
	AllRequiredTags = ActivationRequiredTags; // 设置激活所需标签
	AllBlockedTags = ActivationBlockedTags; // 设置激活阻塞标签

	// 扩展我们的能力标签以添加额外的必需/阻塞标签
	if (LyraASC)
	{
		// 获取额外的激活标签要求
		LyraASC->GetAdditionalActivationTagRequirements(GetAssetTags(), AllRequiredTags, AllBlockedTags);
	}

	// 检查此能力的必需/阻塞标签
	if (AllBlockedTags.Num() || AllRequiredTags.Num())
	{
		// 静态变量，存储能力系统组件拥有的标签
		static FGameplayTagContainer AbilitySystemComponentTags;
		
		// 重置标签容器
		AbilitySystemComponentTags.Reset();
		// 获取能力系统组件拥有的标签
		AbilitySystemComponent.GetOwnedGameplayTags(AbilitySystemComponentTags);

		// 检查是否有任何阻塞标签
		if (AbilitySystemComponentTags.HasAny(AllBlockedTags))
		{
			// 如果玩家已死亡并且由于阻塞标签被拒绝，则提供反馈
			if (OptionalRelevantTags && AbilitySystemComponentTags.HasTag(LyraGameplayTags::Status_Death))
			{
				OptionalRelevantTags->AddTag(LyraGameplayTags::Ability_ActivateFail_IsDead); // 添加死亡激活失败标签
			}

			bBlocked = true; // 标记为被阻塞
		}

		// 检查是否缺少必需标签
		if (!AbilitySystemComponentTags.HasAll(AllRequiredTags))
		{
			bMissing = true; // 标记为缺少标签
		}
	}

	// 检查源标签
	if (SourceTags != nullptr)
	{
		// 检查源阻塞标签和源必需标签
		if (SourceBlockedTags.Num() || SourceRequiredTags.Num())
		{
			// 检查是否有任何源阻塞标签
			if (SourceTags->HasAny(SourceBlockedTags))
			{
				bBlocked = true; // 标记为被阻塞
			}

			// 检查是否缺少源必需标签
			if (!SourceTags->HasAll(SourceRequiredTags))
			{
				bMissing = true; // 标记为缺少标签
			}
		}
	}

	// 检查目标标签
	if (TargetTags != nullptr)
	{
		// 检查目标阻塞标签和目标必需标签
		if (TargetBlockedTags.Num() || TargetRequiredTags.Num())
		{
			// 检查是否有任何目标阻塞标签
			if (TargetTags->HasAny(TargetBlockedTags))
			{
				bBlocked = true; // 标记为被阻塞
			}

			// 检查是否缺少目标必需标签
			if (!TargetTags->HasAll(TargetRequiredTags))
			{
				bMissing = true; // 标记为缺少标签
			}
		}
	}

	// 处理阻塞情况
	if (bBlocked)
	{
		// 如果提供了可选相关标签且阻塞标签有效，则添加阻塞标签
		if (OptionalRelevantTags && BlockedTag.IsValid())
		{
			OptionalRelevantTags->AddTag(BlockedTag);
		}
		return false; // 返回false，表示不满足要求
	}
	// 处理缺失标签情况
	if (bMissing)
	{
		// 如果提供了可选相关标签且缺失标签有效，则添加缺失标签
		if (OptionalRelevantTags && MissingTag.IsValid())
		{
			OptionalRelevantTags->AddTag(MissingTag);
		}
		return false; // 返回false，表示不满足要求
	}

	return true; // 返回true，表示满足所有标签要求
}

/**
 * 当Pawn头像设置时的回调函数
 */
void ULyraGameplayAbility::OnPawnAvatarSet()
{
	// 调用蓝图事件：Pawn头像被设置
	K2_OnPawnAvatarSet();
}

/**
 * 获取能力来源信息
 */
void ULyraGameplayAbility::GetAbilitySource(FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, float& OutSourceLevel, const ILyraAbilitySourceInterface*& OutAbilitySource, AActor*& OutEffectCauser) const
{
	// 初始化输出参数
	OutSourceLevel = 0.0f; // 来源等级
	OutAbilitySource = nullptr; // 能力来源接口
	OutEffectCauser = nullptr; // 效果引发者

	// 效果引发者默认为Avatar角色
	OutEffectCauser = ActorInfo->AvatarActor.Get();

	// 如果能力是由能力信息源添加的，使用它
	UObject* SourceObject = GetSourceObject(Handle, ActorInfo); // 获取源对象

	// 尝试将源对象转换为能力来源接口
	OutAbilitySource = Cast<ILyraAbilitySourceInterface>(SourceObject);
}

/**
 * 尝试在生成时激活能力
 */
void ULyraGameplayAbility::TryActivateAbilityOnSpawn(const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilitySpec& Spec) const
{
	// 如果激活策略是在生成时激活，则尝试激活
	if (ActorInfo && !Spec.IsActive() && (ActivationPolicy == ELyraAbilityActivationPolicy::OnSpawn))
	{
		// 获取能力系统组件和Avatar角色
		UAbilitySystemComponent* ASC = ActorInfo->AbilitySystemComponent.Get();
		const AActor* AvatarActor = ActorInfo->AvatarActor.Get();

		// 如果Avatar角色未被拆除且生命周期大于0，则尝试激活
		if (ASC && AvatarActor && !AvatarActor->GetTearOff() && (AvatarActor->GetLifeSpan() <= 0.0f))
		{
			// 确定是否为本地执行
			const bool bIsLocalExecution = (NetExecutionPolicy == EGameplayAbilityNetExecutionPolicy::LocalPredicted) || (NetExecutionPolicy == EGameplayAbilityNetExecutionPolicy::LocalOnly);
			// 确定是否为服务器执行
			const bool bIsServerExecution = (NetExecutionPolicy == EGameplayAbilityNetExecutionPolicy::ServerOnly) || (NetExecutionPolicy == EGameplayAbilityNetExecutionPolicy::ServerInitiated);

			// 客户端是否应该激活
			const bool bClientShouldActivate = ActorInfo->IsLocallyControlled() && bIsLocalExecution;
			// 服务器是否应该激活
			const bool bServerShouldActivate = ActorInfo->IsNetAuthority() && bIsServerExecution;

			// 如果客户端或服务器应该激活，则尝试激活能力
			if (bClientShouldActivate || bServerShouldActivate)
			{
				ASC->TryActivateAbility(Spec.Handle); // 尝试激活能力
			}
		}
	}
}

/**
 * 检查是否可以更改激活组
 */
bool ULyraGameplayAbility::CanChangeActivationGroup(ELyraAbilityActivationGroup NewGroup) const
{
	// 如果能力未实例化或未激活，则不能更改激活组
	if (!IsInstantiated() || !IsActive())
	{
		return false;
	}

	// 如果新旧激活组相同，则允许更改
	if (ActivationGroup == NewGroup)
	{
		return true;
	}

	// 获取Lyra能力系统组件
	ULyraAbilitySystemComponent* LyraASC = GetLyraAbilitySystemComponentFromActorInfo();
	check(LyraASC); // 确保组件有效

	// 如果当前激活组不是独占阻塞组，且新组被阻塞，则不能更改
	if ((ActivationGroup != ELyraAbilityActivationGroup::Exclusive_Blocking) && LyraASC->IsActivationGroupBlocked(NewGroup))
	{
		return false; // 返回false，表示不能更改
	}

	// 如果新组是可替换组，且能力不能被取消，则不能更改
	if ((NewGroup == ELyraAbilityActivationGroup::Exclusive_Replaceable) && !CanBeCanceled())
	{
		return false; // 返回false，表示不能更改
	}

	return true; // 返回true，表示可以更改
}

/**
 * 更改激活组
 */
bool ULyraGameplayAbility::ChangeActivationGroup(ELyraAbilityActivationGroup NewGroup)
{
	// 确保能力已实例化，否则返回false
	ENSURE_ABILITY_IS_INSTANTIATED_OR_RETURN(ChangeActivationGroup, false);

	// 检查是否可以更改激活组
	if (!CanChangeActivationGroup(NewGroup))
	{
		return false; // 返回false，表示更改失败
	}

	// 如果新旧激活组不同，则进行更改
	if (ActivationGroup != NewGroup)
	{
		// 获取Lyra能力系统组件
		ULyraAbilitySystemComponent* LyraASC = GetLyraAbilitySystemComponentFromActorInfo();
		check(LyraASC); // 确保组件有效

		// 从当前激活组中移除能力
		LyraASC->RemoveAbilityFromActivationGroup(ActivationGroup, this);
		// 将能力添加到新的激活组
		LyraASC->AddAbilityToActivationGroup(NewGroup, this);

		// 更新激活组
		ActivationGroup = NewGroup;
	}

	return true; // 返回true，表示更改成功
}

/**
 * 设置相机模式
 */
void ULyraGameplayAbility::SetCameraMode(TSubclassOf<ULyraCameraMode> CameraMode)
{
	// 确保能力已实例化，否则返回
	ENSURE_ABILITY_IS_INSTANTIATED_OR_RETURN(SetCameraMode, );

	// 获取英雄组件
	if (ULyraHeroComponent* HeroComponent = GetHeroComponentFromActorInfo())
	{
		// 设置能力相机模式
		HeroComponent->SetAbilityCameraMode(CameraMode, CurrentSpecHandle);
		// 更新活动相机模式
		ActiveCameraMode = CameraMode;
	}
}

/**
 * 清除相机模式
 */
void ULyraGameplayAbility::ClearCameraMode()
{
	// 确保能力已实例化，否则返回
	ENSURE_ABILITY_IS_INSTANTIATED_OR_RETURN(ClearCameraMode, );

	// 如果存在活动相机模式，则清除它
	if (ActiveCameraMode)
	{
		// 获取英雄组件
		if (ULyraHeroComponent* HeroComponent = GetHeroComponentFromActorInfo())
		{
			// 清除能力相机模式
			HeroComponent->ClearAbilityCameraMode(CurrentSpecHandle);
		}

		// 重置活动相机模式
		ActiveCameraMode = nullptr;
	}
}